﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ContentRenderingApi;
using ContentRenderingApi.Interfaces.Function;
using ContentRenderingApi.Extender;
using ContentRenderingApi.Tool;

namespace SmoLiteApi.Sql
{
    /// <summary/>
    internal class CommonIndexCreateSql : AbstractSql
    {
        /// <summary/>
        private class FirstConditional : ConditionalFunctionInterface
        {
            private bool _flag;

            /// <summary/>
            internal FirstConditional()
            {
                this._flag = true;
            }

            /// <summary/>
            bool ConditionalFunctionInterface.Invoke(NodeExtender nodeExtender)
            {
                // record the value
                bool flag = this._flag;

                // is set then clear
                if (this._flag)
                {
                    this._flag = false;
                }

                return flag;
            }
        }

        /// <summary/>
        protected override string TemplateTypeName
        {
            get { return Constant.TEMPLATE_TYPE_NAME_COMMON_INDEX_CREATE; }
        }

        /// <summary/>
        protected override void ConfigureTemplate(AbstractTemplate template)
        {
            FirstConditional notIncludeFirstConditional = new FirstConditional();
            FirstConditional includeFirstConditional = new FirstConditional();

            // add the flags
            template.AddConditionalFunction(Constant.ATTRIBUTE_FIRST_NOT_INCLUDE, notIncludeFirstConditional);
            template.AddConditionalFunction(Constant.ATTRIBUTE_FIRST_INCLUDE, includeFirstConditional);
            template.AddConditionalFunction(Constant.ATTRIBUTE_LAST, value => value.Position == value.Length);
            template.AddConditionalFunction(Constant.ATTRIBUTE_HAS_INCLUDES, CommonIndexCreateSql.HasIncludes);

            // sort the index columns
            template.AddChildSort(new string[] { "IndexedColumns" }, "Ordinal", typeof(byte), (left, right) => ((byte)left[0]).CompareTo((byte)right[0]));

            // remove carriage returns and line feeds
            template.AssignDocumentOverride(CommonIndexCreateSql.RemoveLineFeeds);
        }
    
        /// <summary/>
        private static string RemoveLineFeeds(string value)
        {
            return value.Replace(Constant.STRING_LINE_FEED_CARRIAGE_RETURN, string.Empty);
        }

        /// <summary/>
        private static bool HasIncludes(NodeExtender nodeExtender)
        {
            NodeExtender[] indexedColumnNodeExtenders = nodeExtender.FetchRootNodes(Constant.ATTRIBUTE_INDEXED_COLUMNS);

            // check each value
            foreach (NodeExtender indexedColumnNodeExtender in indexedColumnNodeExtenders)
            {
                // check the property
                if (indexedColumnNodeExtender.FetchRawProperty<Boolean>(Constant.ATTRIBUTE_IS_INCLUDED))
                {
                    return true;
                }
            }

            // no includes were found
            return false;
        }
    }
}
